package tp.pr3.instructions;

import tp.pr3.NavigationModule;
import tp.pr3.RobotEngine;
import tp.pr3.instructions.exceptions.InstructionExecutionException;
import tp.pr3.instructions.exceptions.WrongInstructionFormatException;
import tp.pr3.items.Item;
import tp.pr3.items.ItemContainer;
import tp.pr3.util.InstructionParser;
import tp.pr3.util.Messages;

public class OperateInstruction implements Instruction {

	@Override
	public Instruction parse(String cad) throws WrongInstructionFormatException {
		inputId = InstructionParser.getArg(InstructionParser.parseCommand(cad, CmdDic.operateCommand));
		return this;
	}

	@Override
	public String getHelp() {
		return CmdDic.operateHelp;
	}

	@Override
	public void configureContext(RobotEngine engine, NavigationModule navigation, ItemContainer robotContainer) {
		this.robotEngine = engine;
		this.navigationModule = navigation;
		this.robotContainer = robotContainer;
	}

	/**
	 * Uses an item from the pocket, which ID is defined by the argument of the instruction
	 */
	@Override
	public void execute() throws InstructionExecutionException {
		Item temp = this.robotContainer.getItem(inputId);
		if (temp == null)
			throw new InstructionExecutionException(Messages.OUTPUT_OPERATE_NOITEM + inputId); 
		else {
			//de ser usado, el objeto dirá qué ha hecho. Si no, saltará el fallo y lo mostrará el robot.
			if (!temp.use(this.robotEngine, this.navigationModule))
				throw new InstructionExecutionException(Messages.OUTPUT_OPERATE_FAIL + inputId);
			
			//si ya no puede ser usado lo quitamos
			if (!temp.canBeUsed()) {
				this.robotContainer.pickItem(inputId);
				this.robotEngine.robotSays(Messages.OUTPUT_OPERATE_USED.replace("<id>", inputId));
				return; 
			}
		}
	}

	
	private String inputId = "";

	
	private RobotEngine robotEngine;
	private NavigationModule navigationModule;
	private ItemContainer robotContainer;
}
